<!--
 * @Author: 小花
 * @Date: 2022-05-12 16:03:07
 * @LastEditors: 小花
 * @LastEditTime: 2022-05-16 21:38:40
 * @FilePath: /vue3-teap/src/components/RolePermission.vue
 * @Description:
-->
<template>
  <el-card class="box-card" v-for="item in rolePermissionTree" :key="item.id">
    <template #header>
      <el-divider> 基本权限设置 </el-divider>
      <div class="card-header">
        <span> {{item.label}} </span>
        <div class="saveRolePerm">
          <button @click="permissionFn(item.id)">
            授&nbsp;&nbsp;&nbsp;&nbsp;权
            <span></span>
          </button>
        </div>
      </div>
    </template>
    <el-tree :data="[item]" :default-checked-keys="defaultCheckedKeys(item.id)" node-key="id"
      :ref="setTreeRef" :props="defaultProps" show-checkbox />
  </el-card>
</template>

<script lang='ts'>
import { defineComponent, reactive, toRefs } from 'vue'
import { pullPermission, pullRolePermission, addRolePermission } from '@/plugins/request/http'
import RolePermissionData, { defaultProps, IRolePermission, IRolePermissionTree } from '@/model/main/layout/dynamicNav/PermissionPage/RolePermission'
import { useStore } from '@/plugins/store/store'
import { ElTree, ElMessage } from 'element-plus'
import { responseUtil } from '@/plugins/request/responseUtil'
import { TreeKey } from 'element-plus/es/components/tree/src/tree.type'
import nProgress from 'nprogress'

export default defineComponent({
  name: 'RolePermission',
  setup () {
    const store = useStore()
    const coreData = reactive(new RolePermissionData())

    /**
     * @description: 后端获取角色权限关联信息
     * @param {*}
     * @return {*}
     */
    const execPullRolePermission = async () => {
      nProgress.start()
      const result = await (await pullRolePermission()).data as responseUtil<IRolePermission[]>

      const keys = new Set<string>()
      result.data?.forEach(item => {
        keys.add(item.roleId)
      })

      keys?.forEach(key => {
        coreData.rolePermissionMap.set(key, result.data.map(item => item.roleId === key && item.permissionId) as string[])
      })
      nProgress.done()
    }
    execPullRolePermission()

    /**
     * @description: 当缓存中不存在权限信息，则获取权限信息
     * @param {*}
     * @return {*}
     */
    const initPermission = async () => {
      if (!store.permission) {
        store.permission = await (await pullPermission()).data.data
      }
    }
    initPermission()

    /**
     * @description: 创建权限树
     * @param {*}
     * @return {*}
     */
    const createTree = () => {
      store.role?.forEach(role => {
        const obj: IRolePermissionTree = {
          id: role.roleId,
          label: role.roleName,
          children: [] as IRolePermissionTree[]
        }

        store.permission.forEach(perm => {
          obj.children!.push({
            id: perm.permId,
            label: perm.permName
          })
        })
        coreData.rolePermissionTree.push(obj)
      })
    }
    createTree()

    /**
     * @description: 页面树加载角色已经授权信息
     * @param {*} role
     * @return {*}
     */
    const defaultCheckedKeys = (role: string) => {
      return coreData.rolePermissionMap.get(role)
    }

    /**
     * @description: 获取页面树形控件ref
     * @param {*} ev
     * @return {*}
     */
    const setTreeRef = (ev: InstanceType<typeof ElTree>) => {
      if (ev) coreData.treeRef.set((ev.data[0] as any).id, ev)
    }

    /**
     * @description: 添加或更新权限
     * @param {*} roleId
     * @return {*}
     */
    const permissionFn = async (roleId: string) => {
      const ref = coreData.treeRef.get(roleId)
      const data = {
        roleId,
        permissionId: [] as TreeKey[]
      }
      if (ref) {
        nProgress.start()
        data.permissionId = ref.getCheckedKeys(true)
        const result = await (await addRolePermission(data)).data as responseUtil
        if (result.code !== 43000) {
          ElMessage.error(result.msg)
          nProgress.done()
          return
        }
        ElMessage.success(result.msg)
        nProgress.done()
      }
    }

    return {
      ...toRefs(coreData),
      defaultProps,
      permissionFn,
      setTreeRef,
      defaultCheckedKeys
    }
  }
})
</script>

<style lang='scss' scoped>
@import '@/assets/scss/addRoleButton.scss';
@import '@/assets/scss/saveRolePermButton.scss';

.box-card {
  margin-bottom: 2rem;
  user-select: none;
  .card-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    span {
      display: inline-block;
      font-weight: bold;
      letter-spacing: 2px;
    }
    .saveRolePerm {
      display: flex;
      justify-content: center;
    }
  }
}
</style>
